package cam.School.DataAccessObjectImpl;

import static cam.School.DataAccessObject.DAOUtil.close;
import static cam.School.DataAccessObject.DAOUtil.prepareStatement;
import static cam.School.DataAccessObject.DAOUtil.toSqlDate;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import cam.School.DAOException.DAOException;
import cam.School.DataAccessObject.DAOFactory;
import cam.School.DataAccessObject.PaymentDAO;
import cam.School.DataTransfertObject.CallResult;
import cam.School.DataTransfertObject.PaymentDTO;


public class PaymentDAOImpl implements PaymentDAO  {

// Constants ----------------------------------------------------------------------------------
	
	
    private static final String QUERY_PARAMS_GET_ALL ="id, origin, destination, executionDate,"+
                         " quarter, executeBy, type, amount";
        
    private static final String UPDATE_QUERY_PARAMS = " origin = ?, destination = ?, executionDate = ?,"+
            " quarter = ?, executeBy = ?, type = ?, amount = ?";
    
    
    private static final String SQL_FIND_BY_ORIGIN = "SELECT "+ 
    		QUERY_PARAMS_GET_ALL + " FROM payment WHERE  origin = ?";
    
    private static final String INSERT_PARAMS = "(origin, destination, executionDate, quarter,executeBy, type, amount)";
    
    private static final String SQL_INSERT =
            "INSERT INTO payment "+INSERT_PARAMS+" VALUES (?, ?, ?, ?, ?, ?, ?)";
        
    
   
    private DAOFactory daoFactory;
    
 // Constructors -------------------------------------------------------------------------------

    /**
     * Construct an User DAO for the given DAOFactory. Package private so that it can be constructed
     * inside the DAO package only.
     * @param daoFactory The DAOFactory to construct this User DAO for.
     */
    public PaymentDAOImpl(DAOFactory daoFactory) {
        this.daoFactory = daoFactory;
    }
	@Override
	public PaymentDTO getById(Long id) throws DAOException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<PaymentDTO> getAll() throws DAOException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public CallResult add(PaymentDTO payment) throws IllegalArgumentException,
			DAOException {
		Object[] values = {
				payment.getOrigin(), 
				payment.getDestination(), 
				toSqlDate(new Date()),
				payment.getQuarter(),
				payment.getExecuteBy(), 
				payment.getType(),
				payment.getAmount()				
		};

		Connection connection = null;
		PreparedStatement preparedStatement = null;

		try {
			connection = daoFactory.getConnection();
			preparedStatement = prepareStatement(connection, SQL_INSERT, false,
					values);
			int affectedRows = preparedStatement.executeUpdate();			
			if (affectedRows == 0) {
				return new CallResult(404, "not created");
			} else {
				return new CallResult(200, "created");
			}
		} catch (SQLException e) {
			return new CallResult(404, e.toString());
		} finally {
			close(connection, preparedStatement);
		}
	}

	@Override
	public void update(PaymentDTO payment) throws IllegalArgumentException,
			DAOException {
		// TODO Auto-generated method stub
		
	}

	@Override
	public boolean delete(int paymentId) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public List<PaymentDTO> getByTo(long to) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<PaymentDTO> getByFrom(long from) {
		Object[] values = {from};
		return getAll(SQL_FIND_BY_ORIGIN, values);			
	}

	private PaymentDTO map(ResultSet resultSet)
			throws SQLException {
		PaymentDTO payment = new PaymentDTO();
		payment.setId(resultSet.getLong("id"));
		payment.setOrigin(resultSet.getLong("origin"));
		payment.setDestination(resultSet.getLong("destination"));
		payment.setExecutionDate(resultSet.getDate("executionDate"));
		payment.setQuarter(resultSet.getString("quarter"));
		payment.setExecuteBy(resultSet.getString("executeBy"));
		payment.setType(resultSet.getString("type"));	
		return payment;
	}
	
	public List<PaymentDTO> getAll(String sqlQuery, Object... values) throws DAOException {
		Connection connection = null;
		PreparedStatement preparedStatement = null;
		ResultSet resultSet = null;
		List<PaymentDTO> payments = new ArrayList<PaymentDTO>();

		try {
			connection = daoFactory.getConnection();
			if(values.length == 0 ){
				preparedStatement = connection.prepareStatement(sqlQuery);
			}else{
				preparedStatement = prepareStatement(connection, sqlQuery, false, values);
			}
			
			resultSet = preparedStatement.executeQuery();
			while (resultSet.next()) {
				payments.add(map(resultSet));
			}
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			close(connection, preparedStatement, resultSet);
		}
		return payments;
	}

	@Override
	public List<PaymentDTO> getByQuarter(String quarter) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<PaymentDTO> getByExecutedBy(String name) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<PaymentDTO> getByExecutionDate(Date date) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public PaymentDTO getByRange(Date from, Date to) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int update(long id) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public List<PaymentDTO> getByOrganisatorId(long organisatorId) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<PaymentDTO> getByMatriculNumber(String matriculNumber) {
		// TODO Auto-generated method stub
		return null;
	}

}
